package com.axjy.scheduler.service.impl;

import cn.hutool.core.util.IdUtil;
import com.axjy.comm.pojo.TpScheduler;
import com.axjy.comm.pojo.TpSchedulerSeat;
import com.axjy.comm.pojo.TpSchedulerSeatPrice;
import com.axjy.comm.util.TpConst;
import com.axjy.comm.util.TpContext;
import com.axjy.scheduler.config.RedissonConfig;
import com.axjy.scheduler.mapper.SchedulerMapper;
import com.axjy.scheduler.mapper.SchedulerSeatMapper;
import com.axjy.scheduler.mapper.SchedulerSeatPriceMapper;
import com.axjy.scheduler.service.SubmitOrderService;
import com.axjy.scheduler.vo.CreateOrderMessage;
import com.axjy.scheduler.vo.CreateOrderVo;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.redisson.api.RLock;
import org.redisson.api.RSet;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@Service("submitOrderService")
public class SubmitOrderServiceImpl implements SubmitOrderService {

    @Resource
    private RedissonClient redissonClient;

    @Resource
    private SchedulerMapper schedulerMapper;

    @Resource
    private SchedulerSeatMapper schedulerSeatMapper;

    @Resource
    private SchedulerSeatPriceMapper schedulerSeatPriceMapper;


    private RabbitTemplate rabbitTemplate;

    @Resource
    public void setRabbitTemplate(RabbitTemplate rabbitTemplate) {
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        this.rabbitTemplate = rabbitTemplate;
    }

    @Override
    public Map<String,String> submitOrder(CreateOrderVo createOrderVo) {
        //从TheadLocal中取出userId设置到vo中
       Integer userId=   TpContext.getLoginUserTl();
        System.out.println("===>"+userId);
        createOrderVo.setUserId(userId);
        //根据雪花算法得到唯一的一个编号
        String orderNo=IdUtil.getSnowflake(1,1).nextId()+"";
        String seatPositions= createOrderVo.getSeatPositions();
        String[] arr=seatPositions.split(",");
        if(arr.length<=0){
            throw new RuntimeException("创建订单失败!");
        }
        RLock[] locks=new RLock[arr.length];
        for(int i=0;i< locks.length;i++){
            locks[i]=redissonClient.getLock(arr[i]);
        }
        RLock lock=redissonClient.getMultiLock(locks);
        try {
            lock.lock();
            String usedSeatKey="usedseat:"+createOrderVo.getSchedulerId();
            RSet<String> usedSeatSet= redissonClient.getSet(usedSeatKey);
            for(String seat:arr) {
                if(usedSeatSet.contains(seat)){
                    throw new RuntimeException("该座位已经抢占!");
                }
            }

            CreateOrderMessage createOrderMessage=new CreateOrderMessage();
            BeanUtils.copyProperties(createOrderVo,createOrderMessage);
           Double totalAmount=0.0; //总价
            createOrderMessage.setOrderNo(orderNo);
           for(String seat:arr){
               String[] xy=seat.split("_");
               QueryWrapper<TpSchedulerSeat> queryWrapper= Wrappers.query();
               queryWrapper.eq("x",Integer.valueOf(xy[0]));
               queryWrapper.eq("y",Integer.valueOf(xy[1]));
               queryWrapper.eq("schedule_id",createOrderVo.getSchedulerId());
               TpSchedulerSeat tpSchedulerSeat= schedulerSeatMapper.selectOne(queryWrapper);
               tpSchedulerSeat.setOrderNo(orderNo);
               tpSchedulerSeat.setStatus(2);
               tpSchedulerSeat.setUserId(createOrderVo.getUserId());
               tpSchedulerSeat.setUpdatedTime(LocalDateTime.now());
               schedulerSeatMapper.updateById(tpSchedulerSeat);  //改变排期座位状态

               QueryWrapper<TpSchedulerSeatPrice> priceWrapper=Wrappers.query();
               priceWrapper.eq("schedule_id",createOrderVo.getSchedulerId());
               priceWrapper.eq("area_level",tpSchedulerSeat.getAreaLevel());
               TpSchedulerSeatPrice seatPrice= schedulerSeatPriceMapper.selectOne(priceWrapper);
                createOrderMessage.getPriceList().add(seatPrice.getPrice());
               totalAmount+= seatPrice.getPrice();
           }

            createOrderMessage.setTotalAmount(totalAmount);

          TpScheduler tpScheduler= schedulerMapper.selectById(createOrderVo.getSchedulerId());
           createOrderMessage.setItemId(tpScheduler.getItemId());
           createOrderMessage.setCinemaId(tpScheduler.getCinemaId());


            //向中间件发送信息

            System.out.println("----------------发送前");
            rabbitTemplate.convertAndSend(TpConst.SCHEDULE_EXCHANGE,TpConst.SCHEDULE_ORDER_BINDING,createOrderMessage);
            System.out.println("-----------------发送后s");



            //订购的座位放入到一个Set中
           for(String seat:arr){
               usedSeatSet.add(seat);
           }
        }finally {
            lock.unlock();
        }
        Map map=new HashMap();
        map.put("orderNo",orderNo);
        return map;
    }
}
